Merge "Remove leading underscore from methods _getResponse*"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 24 Nov 2013 03:20:23 +0000 (03:20 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 24 Nov 2013 03:20:23 +0000 (03:20 +0000)
1  2 
includes/filebackend/FSFileBackend.php
includes/filebackend/SwiftFileBackend.php

   * @since 1.19
   */
  class FSFileBackend extends FileBackendStore {
 -      protected $basePath; // string; directory holding the container directories
 -      /** @var Array Map of container names to root paths */
 -      protected $containerPaths = array(); // for custom container paths
 -      protected $fileMode; // integer; file permission mode
 -      protected $fileOwner; // string; required OS username to own files
 -      protected $currentUser; // string; OS username running this script
 -
 -      /** @var Array */
 +      /** @var string Directory holding the container directories */
 +      protected $basePath;
 +
 +      /** @var array Map of container names to root paths for custom container paths */
 +      protected $containerPaths = array();
 +
 +      /** @var int File permission mode */
 +      protected $fileMode;
 +
 +      /** @var string Required OS username to own files */
 +      protected $fileOwner;
 +
 +      /** @var string OS username running this script */
 +      protected $currentUser;
 +
 +      /** @var array */
        protected $hadWarningErrors = array();
  
        /**
@@@ -98,7 -90,6 +98,7 @@@
                                return $relStoragePath;
                        }
                }
 +
                return null;
        }
  
                } elseif ( isset( $this->basePath ) ) {
                        return "{$this->basePath}/{$fullCont}";
                }
 +
                return null; // no container base path defined
        }
  
                if ( $relPath != '' ) {
                        $fsPath .= "/{$relPath}";
                }
 +
                return $fsPath;
        }
  
                $dest = $this->resolveToFSPath( $params['dst'] );
                if ( $dest === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        $tempFile = TempFSFile::factory( 'create_', 'tmp' );
                        if ( !$tempFile ) {
                                $status->fatal( 'backend-fail-create', $params['dst'] );
 +
                                return $status;
                        }
                        $this->trapWarnings();
                        $this->untrapWarnings();
                        if ( $bytes === false ) {
                                $status->fatal( 'backend-fail-create', $params['dst'] );
 +
                                return $status;
                        }
                        $cmd = implode( ' ', array(
                        $this->untrapWarnings();
                        if ( $bytes === false ) {
                                $status->fatal( 'backend-fail-create', $params['dst'] );
 +
                                return $status;
                        }
                        $this->chmod( $dest );
        /**
         * @see FSFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseCreate( $errors, Status $status, array $params, $cmd ) {
+       protected function getResponseCreate( $errors, Status $status, array $params, $cmd ) {
                if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) {
                        $status->fatal( 'backend-fail-create', $params['dst'] );
                        trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output
                $dest = $this->resolveToFSPath( $params['dst'] );
                if ( $dest === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                                        trigger_error( __METHOD__ . ": copy() failed but returned true." );
                                }
                                $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
 +
                                return $status;
                        }
                        $this->chmod( $dest );
        /**
         * @see FSFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseStore( $errors, Status $status, array $params, $cmd ) {
+       protected function getResponseStore( $errors, Status $status, array $params, $cmd ) {
                if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) {
                        $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
                        trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output
                $source = $this->resolveToFSPath( $params['src'] );
                if ( $source === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                $dest = $this->resolveToFSPath( $params['dst'] );
                if ( $dest === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-copy', $params['src'] );
                        }
 +
                        return $status; // do nothing; either OK or bad status
                }
  
                                        trigger_error( __METHOD__ . ": copy() failed but returned true." );
                                }
                                $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
 +
                                return $status;
                        }
                        $this->chmod( $dest );
        /**
         * @see FSFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseCopy( $errors, Status $status, array $params, $cmd ) {
+       protected function getResponseCopy( $errors, Status $status, array $params, $cmd ) {
                if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) {
                        $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
                        trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output
                $source = $this->resolveToFSPath( $params['src'] );
                if ( $source === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                $dest = $this->resolveToFSPath( $params['dst'] );
                if ( $dest === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-move', $params['src'] );
                        }
 +
                        return $status; // do nothing; either OK or bad status
                }
  
                        clearstatcache(); // file no longer at source
                        if ( !$ok ) {
                                $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
 +
                                return $status;
                        }
                }
        /**
         * @see FSFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseMove( $errors, Status $status, array $params, $cmd ) {
+       protected function getResponseMove( $errors, Status $status, array $params, $cmd ) {
                if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) {
                        $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
                        trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output
                $source = $this->resolveToFSPath( $params['src'] );
                if ( $source === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-delete', $params['src'] );
                        }
 +
                        return $status; // do nothing; either OK or bad status
                }
  
                        $this->untrapWarnings();
                        if ( !$ok ) {
                                $status->fatal( 'backend-fail-delete', $params['src'] );
 +
                                return $status;
                        }
                }
        /**
         * @see FSFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseDelete( $errors, Status $status, array $params, $cmd ) {
+       protected function getResponseDelete( $errors, Status $status, array $params, $cmd ) {
                if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) {
                        $status->fatal( 'backend-fail-delete', $params['src'] );
                        trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output
                }
        }
  
 +      /**
 +       * @param string $fullCont
 +       * @param $dirRel
 +       * @param array $params
 +       * @return Status
 +       */
        protected function doPrepareInternal( $fullCont, $dirRel, array $params ) {
                $status = Status::newGood();
                list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] );
                if ( is_dir( $dir ) && !$existed ) {
                        $status->merge( $this->doSecureInternal( $fullCont, $dirRel, $params ) );
                }
 +
                return $status;
        }
  
                                $status->fatal( 'backend-fail-create', "{$storeDir}/.htaccess" );
                        }
                }
 +
                return $status;
        }
  
                        }
                        $this->untrapWarnings();
                }
 +
                return $status;
        }
  
                        rmdir( $dir ); // remove directory if empty
                }
                $this->untrapWarnings();
 +
                return $status;
        }
  
  
        /**
         * @see FileBackendStore::getDirectoryListInternal()
 -       * @return Array|null
 +       * @param string $fullCont
 +       * @param string $dirRel
 +       * @param array $params
 +       * @return array|null
         */
        public function getDirectoryListInternal( $fullCont, $dirRel, array $params ) {
                list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] );
                $exists = is_dir( $dir );
                if ( !$exists ) {
                        wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" );
 +
                        return array(); // nothing under this dir
                } elseif ( !is_readable( $dir ) ) {
                        wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" );
 +
                        return null; // bad permissions?
                }
 +
                return new FSFileBackendDirList( $dir, $params );
        }
  
        /**
         * @see FileBackendStore::getFileListInternal()
 -       * @return Array|FSFileBackendFileList|null
 +       * @param string $fullCont
 +       * @param string $dirRel
 +       * @param array $params
 +       * @return array|FSFileBackendFileList|null
         */
        public function getFileListInternal( $fullCont, $dirRel, array $params ) {
                list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] );
                $exists = is_dir( $dir );
                if ( !$exists ) {
                        wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" );
 +
                        return array(); // nothing under this dir
                } elseif ( !is_readable( $dir ) ) {
                        wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" );
 +
                        return null; // bad permissions?
                }
 +
                return new FSFileBackendFileList( $dir, $params );
        }
  
  
                foreach ( $fileOpHandles as $index => $fileOpHandle ) {
                        $status = Status::newGood();
-                       $function = '_getResponse' . $fileOpHandle->call;
+                       $function = 'getResponse' . $fileOpHandle->call;
                        $this->$function( $errs[$index], $status, $fileOpHandle->params, $fileOpHandle->cmd );
                        $statuses[$index] = $status;
                        if ( $status->isOK() && $fileOpHandle->chmodPath ) {
  
        /**
         * Listen for E_WARNING errors and track whether any happen
 -       *
 -       * @return void
         */
        protected function trapWarnings() {
                $this->hadWarningErrors[] = false; // push to stack
        }
  
        /**
 -       * @param integer $errno
 +       * @param int $errno
         * @param string $errstr
         * @return bool
         * @access private
        public function handleWarning( $errno, $errstr ) {
                wfDebugLog( 'FSFileBackend', $errstr ); // more detailed error logging
                $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true;
 +
                return true; // suppress from PHP handler
        }
  }
@@@ -810,7 -761,7 +810,7 @@@ class FSFileOpHandle extends FileBacken
         * @param array $params
         * @param string $call
         * @param string $cmd
 -       * @param integer|null $chmodPath
 +       * @param int|null $chmodPath
         */
        public function __construct(
                FSFileBackend $backend, array $params, $call, $cmd, $chmodPath = null
  abstract class FSFileBackendList implements Iterator {
        /** @var Iterator */
        protected $iter;
 -      protected $suffixStart; // integer
 -      protected $pos = 0; // integer
 -      /** @var Array */
 +
 +      /** @var int */
 +      protected $suffixStart;
 +
 +      /** @var int */
 +      protected $pos = 0;
 +
 +      /** @var array */
        protected $params = array();
  
        /**
                        # RecursiveDirectoryIterator extends FilesystemIterator.
                        # FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x.
                        $flags = FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::SKIP_DOTS;
 +
                        return new RecursiveIteratorIterator(
                                new RecursiveDirectoryIterator( $dir, $flags ),
                                RecursiveIteratorIterator::CHILD_FIRST // include dirs
  
        /**
         * @see Iterator::key()
 -       * @return integer
 +       * @return int
         */
        public function key() {
                return $this->pos;
  
        /**
         * @see Iterator::next()
 -       * @return void
 +       * @throws FileBackendError
         */
        public function next() {
                try {
  
        /**
         * @see Iterator::rewind()
 -       * @return void
 +       * @throws FileBackendError
         */
        public function rewind() {
                $this->pos = 0;
        /**
         * Filter out items by advancing to the next ones
         */
 -      protected function filterViaNext() {}
 +      protected function filterViaNext() {
 +      }
  
        /**
         * Return only the relative path and normalize slashes to FileBackend-style.
         * Uses the "real path" since the suffix is based upon that.
         *
 -       * @param string $path
 +       * @param string $dir
         * @return string
         */
        protected function getRelPath( $dir ) {
                if ( $path === false ) {
                        $path = $dir;
                }
 +
                return strtr( substr( $path, $this->suffixStart ), '\\', '/' );
        }
  }
   * @since 1.19
   */
  class SwiftFileBackend extends FileBackendStore {
 -      /** @var CF_Authentication */
 -      protected $auth; // Swift authentication handler
 -      protected $authTTL; // integer seconds
 -      protected $swiftTempUrlKey; // string; shared secret value for making temp urls
 -      protected $swiftAnonUser; // string; username to handle unauthenticated requests
 -      protected $swiftUseCDN; // boolean; whether CloudFiles CDN is enabled
 -      protected $swiftCDNExpiry; // integer; how long to cache things in the CDN
 -      protected $swiftCDNPurgable; // boolean; whether object CDN purging is enabled
 +      /** @var CF_Authentication Swift authentication handler */
 +      protected $auth;
 +
 +      /** @var int TTL in seconds */
 +      protected $authTTL;
 +
 +      /** @var string Shared secret value for making temp URLs */
 +      protected $swiftTempUrlKey;
 +
 +      /** @var string Username to handle unauthenticated requests */
 +      protected $swiftAnonUser;
 +
 +      /** @var bool Whether CloudFiles CDN is enabled */
 +      protected $swiftUseCDN;
 +
 +      /** @var int How long to cache things in the CDN */
 +      protected $swiftCDNExpiry;
 +
 +      /** @var bool Whether object CDN purging is enabled */
 +      protected $swiftCDNPurgable;
  
        // Rados Gateway specific options
 -      protected $rgwS3AccessKey; // string; S3 access key
 -      protected $rgwS3SecretKey; // string; S3 authentication key
 +      /** @var string S3 access key */
 +      protected $rgwS3AccessKey;
  
 -      /** @var CF_Connection */
 -      protected $conn; // Swift connection handle
 -      protected $sessionStarted = 0; // integer UNIX timestamp
 +      /** @var string S3 authentication key */
 +      protected $rgwS3SecretKey;
 +
 +      /** @var CF_Connection Swift connection handle*/
 +      protected $conn;
 +
 +      /** @var int UNIX timestamp */
 +      protected $sessionStarted = 0;
  
        /** @var CloudFilesException */
        protected $connException;
 -      protected $connErrorTime = 0; // UNIX timestamp
 +
 +      /** @var int UNIX timestamp */
 +      protected $connErrorTime = 0;
  
        /** @var BagOStuff */
        protected $srvCache;
                        } else {
                                try { // look for APC, XCache, WinCache, ect...
                                        $this->srvCache = ObjectCache::newAccelerator( array() );
 -                              } catch ( Exception $e ) {}
 +                              } catch ( Exception $e ) {
 +                              }
                        }
                }
                $this->srvCache = $this->srvCache ? $this->srvCache : new EmptyBagOStuff();
  
        /**
         * @see FileBackendStore::resolveContainerPath()
 -       * @return null
 +       * @param string $container
 +       * @param string $relStoragePath
 +       * @return string|null Returns null when the URL encoded storage path is
 +       *   longer than 1024 characters or not UTF-8 encoded.
         */
        protected function resolveContainerPath( $container, $relStoragePath ) {
                if ( !mb_check_encoding( $relStoragePath, 'UTF-8' ) ) { // mb_string required by CF
                } elseif ( strlen( urlencode( $relStoragePath ) ) > 1024 ) {
                        return null; // too long for Swift
                }
 +
                return $relStoragePath;
        }
  
  
                try {
                        $this->getContainer( $container );
 +
                        return true; // container exists
                } catch ( NoSuchContainerException $e ) {
                } catch ( CloudFilesException $e ) { // some other exception?
                if ( isset( $headers['Content-Disposition'] ) ) {
                        $headers['Content-Disposition'] = $this->truncDisp( $headers['Content-Disposition'] );
                }
 +
                return $headers;
        }
  
                                break; // too long; sigh
                        }
                }
 +
                return $res;
        }
  
                list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
                if ( $dstRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        $dContObj = $this->getContainer( $dstCont );
                } catch ( NoSuchContainerException $e ) {
                        $status->fatal( 'backend-fail-create', $params['dst'] );
 +
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
        /**
         * @see SwiftFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseCreate( CF_Async_Op $cfOp, Status $status, array $params ) {
+       protected function getResponseCreate( CF_Async_Op $cfOp, Status $status, array $params ) {
                try {
                        $cfOp->getLastResponse();
                } catch ( BadContentTypeException $e ) {
                list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
                if ( $dstRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        $dContObj = $this->getContainer( $dstCont );
                } catch ( NoSuchContainerException $e ) {
                        $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
 +
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
                wfRestoreWarnings();
                if ( $sha1Hash === false ) { // source doesn't exist?
                        $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
 +
                        return $status;
                }
                $sha1Hash = wfBaseConvert( $sha1Hash, 16, 36, 31 );
        /**
         * @see SwiftFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseStore( CF_Async_Op $cfOp, Status $status, array $params ) {
+       protected function getResponseStore( CF_Async_Op $cfOp, Status $status, array $params ) {
                try {
                        $cfOp->getLastResponse();
                } catch ( BadContentTypeException $e ) {
                list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                if ( $srcRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
                if ( $dstRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
                                $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
                        }
 +
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
        /**
         * @see SwiftFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseCopy( CF_Async_Op $cfOp, Status $status, array $params ) {
+       protected function getResponseCopy( CF_Async_Op $cfOp, Status $status, array $params ) {
                try {
                        $cfOp->getLastResponse();
                } catch ( NoSuchObjectException $e ) { // source object does not exist
                list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                if ( $srcRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
                if ( $dstRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
 +
                        return $status;
                }
  
                        if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
                                $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
                        }
 +
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
        /**
         * @see SwiftFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseMove( CF_Async_Op $cfOp, Status $status, array $params ) {
+       protected function getResponseMove( CF_Async_Op $cfOp, Status $status, array $params ) {
                try {
                        $cfOp->getLastResponse();
                } catch ( NoSuchObjectException $e ) { // source object does not exist
                list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                if ( $srcRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
        /**
         * @see SwiftFileBackend::doExecuteOpHandlesInternal()
         */
-       protected function _getResponseDelete( CF_Async_Op $cfOp, Status $status, array $params ) {
+       protected function getResponseDelete( CF_Async_Op $cfOp, Status $status, array $params ) {
                try {
                        $cfOp->getLastResponse();
                } catch ( NoSuchContainerException $e ) {
                list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                if ( $srcRel === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
 +
                        return $status;
                }
  
                // (a) Check if container already exists
                try {
                        $this->getContainer( $fullCont );
 +
                        // NoSuchContainerException not thrown: container must exist
                        return $status; // already exists
                } catch ( NoSuchContainerException $e ) {
                        // NoSuchContainerException thrown: container does not exist
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
                        // CDN not enabled; nothing to see here
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
  
        /**
         * @see FileBackendStore::doSecureInternal()
 +       * @param string $fullCont
 +       * @param string $dir
 +       * @param array $params
         * @return Status
         */
        protected function doSecureInternal( $fullCont, $dir, array $params ) {
  
        /**
         * @see FileBackendStore::doPublishInternal()
 +       * @param string $fullCont
 +       * @param string $dir
 +       * @param array $params
         * @return Status
         */
        protected function doPublishInternal( $fullCont, $dir, array $params ) {
                        return $status; // ok, nothing to do
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
                                return $status; // race? consistency delay?
                        } catch ( CloudFilesException $e ) { // some other exception?
                                $this->handleException( $e, $status, __METHOD__, $params );
 +
                                return $status;
                        }
                }
         */
        protected function convertSwiftDate( $ts, $format = TS_MW ) {
                $timestamp = new MWTimestamp( $ts );
 +
                return $timestamp->getTimestamp( $format );
        }
  
                                        $obj->setMetadataValues( array( 'Sha1base36' => $hash ) );
                                        $obj->sync_metadata(); // save to Swift
                                        wfProfileOut( __METHOD__ );
 +
                                        return true; // success
                                }
                        }
                trigger_error( "Unable to set SHA-1 metadata for $path", E_USER_WARNING );
                $obj->setMetadataValues( array( 'Sha1base36' => false ) );
                wfProfileOut( __METHOD__ );
 +
                return false; // failed
        }
  
  
        /**
         * @see FileBackendStore::doDirectoryExists()
 +       * @param string $fullCont
 +       * @param string $dir
 +       * @param array $params
         * @return bool|null
         */
        protected function doDirectoryExists( $fullCont, $dir, array $params ) {
                try {
                        $container = $this->getContainer( $fullCont );
                        $prefix = ( $dir == '' ) ? null : "{$dir}/";
 +
                        return ( count( $container->list_objects( 1, null, $prefix ) ) > 0 );
                } catch ( NoSuchContainerException $e ) {
                        return false;
  
        /**
         * @see FileBackendStore::getDirectoryListInternal()
 +       * @param string $fullCont
 +       * @param string $dir
 +       * @param array $params
         * @return SwiftFileBackendDirList
         */
        public function getDirectoryListInternal( $fullCont, $dir, array $params ) {
  
        /**
         * @see FileBackendStore::getFileListInternal()
 +       * @param string $fullCont
 +       * @param string $dir
 +       * @param array $params
         * @return SwiftFileBackendFileList
         */
        public function getFileListInternal( $fullCont, $dir, array $params ) {
         * @param string $fullCont Resolved container name
         * @param string $dir Resolved storage directory with no trailing slash
         * @param string|null $after Resolved container relative path to list items after
 -       * @param integer $limit Max number of items to list
 +       * @param int $limit Max number of items to list
         * @param array $params Parameters for getDirectoryList()
 -       * @return Array List of container relative resolved paths of directories directly under $dir
 +       * @return array List of container relative resolved paths of directories directly under $dir
         * @throws FileBackendError
         */
        public function getDirListPageInternal( $fullCont, $dir, &$after, $limit, array $params ) {
         * @param string $fullCont Resolved container name
         * @param string $dir Resolved storage directory with no trailing slash
         * @param string|null $after Resolved container relative path of file to list items after
 -       * @param integer $limit Max number of items to list
 +       * @param int $limit Max number of items to list
         * @param array $params Parameters for getDirectoryList()
 -       * @return Array List of resolved container relative paths of files under $dir
 +       * @return array List of resolved container relative paths of files under $dir
         * @throws FileBackendError
         */
        public function getFileListPageInternal( $fullCont, $dir, &$after, $limit, array $params ) {
                try {
                        $container = $this->getContainer( $fullCont );
                        $prefix = ( $dir == '' ) ? null : "{$dir}/";
 -                      $objects = array(); // list of unfiltered names or CF_Object items
 +
 +                      // $objects will contain a list of unfiltered names or CF_Object items
                        // Non-recursive: only list files right under $dir
                        if ( !empty( $params['topOnly'] ) ) {
                                if ( !empty( $params['adviseStat'] ) ) {
                        if ( is_object( $object ) ) {
                                $stat = array(
                                        // Convert various random Swift dates to TS_MW
 -                                      'mtime'  => $this->convertSwiftDate( $object->last_modified, TS_MW ),
 -                                      'size'   => (int)$object->content_length,
 +                                      'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
 +                                      'size' => (int)$object->content_length,
                                        'latest' => false // eventually consistent
                                );
                                $names[] = array( $object->name, $stat );
                                $names[] = array( $object, null );
                        }
                }
 +
                return $names;
        }
  
         *
         * @param string $path Storage path
         * @param array $val Stat value
 -       * @return void
         */
        public function loadListingStatInternal( $path, array $val ) {
                $this->cheapCache->set( $path, 'stat', $val );
                                $this->clearCache( array( $params['src'] ) );
                                $stat = $this->getFileStat( $params );
                        }
 +
                        return $stat['sha1'];
                } else {
                        return false;
                        $cont = $this->getContainer( $srcCont );
                } catch ( NoSuchContainerException $e ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
 +
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
 +
                        return $status;
                }
  
  
        public function getFileHttpUrl( array $params ) {
                if ( $this->swiftTempUrlKey != '' ||
 -                      ( $this->rgwS3AccessKey != '' && $this->rgwS3SecretKey != '' ) )
 -              {
 +                      ( $this->rgwS3AccessKey != '' && $this->rgwS3SecretKey != '' )
 +              {
                        list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                        if ( $srcRel === null ) {
                                return null; // invalid path
                                                $this->rgwS3SecretKey,
                                                true // raw
                                        ) );
 +
                                        // See http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html.
                                        // Note: adding a newline for empty CanonicalizedAmzHeaders does not work.
                                        return wfAppendQuery(
                                $this->handleException( $e, null, __METHOD__, $params );
                        }
                }
 +
                return null;
        }
  
         * $params is currently only checked for a 'latest' flag.
         *
         * @param array $params
 -       * @return Array
 +       * @return array
         */
        protected function headersFromParams( array $params ) {
                $hdrs = array();
                if ( !empty( $params['latest'] ) ) {
                        $hdrs[] = 'X-Newest: true';
                }
 +
                return $hdrs;
        }
  
                $cfOps = $batch->execute();
                foreach ( $cfOps as $index => $cfOp ) {
                        $status = Status::newGood();
-                       $function = '_getResponse' . $fileOpHandles[$index]->call;
+                       $function = 'getResponse' . $fileOpHandles[$index]->call;
                        try { // catch exceptions; update status
                                $this->$function( $cfOp, $status, $fileOpHandles[$index]->params );
                                $this->purgeCDNCache( $fileOpHandles[$index]->affectedObjects );
        /**
         * Set read/write permissions for a Swift container.
         *
 -       * $readGrps is a list of the possible criteria for a request to have
 +       * @see http://swift.openstack.org/misc.html#acls
 +       *
 +       * In general, we don't allow listings to end-users. It's not useful, isn't well-defined
 +       * (lists are truncated to 10000 item with no way to page), and is just a performance risk.
 +       *
 +       * @param CF_Container $contObj Swift container
 +       * @param array $readGrps List of the possible criteria for a request to have
         * access to read a container. Each item is one of the following formats:
         *   - account:user        : Grants access if the request is by the given user
         *   - ".r:<regex>"        : Grants access if the request is from a referrer host that
         *                           Setting this to '*' effectively makes a container public.
         *   -".rlistings:<regex>" : Grants access if the request is from a referrer host that
         *                           matches the expression and the request is for a listing.
 -       *
 -       * $writeGrps is a list of the possible criteria for a request to have
 +       * @param array $writeGrps A list of the possible criteria for a request to have
         * access to write to a container. Each item is of the following format:
         *   - account:user       : Grants access if the request is by the given user
 -       *
 -       * @see http://swift.openstack.org/misc.html#acls
 -       *
 -       * In general, we don't allow listings to end-users. It's not useful, isn't well-defined
 -       * (lists are truncated to 10000 item with no way to page), and is just a performance risk.
 -       *
 -       * @param CF_Container $contObj Swift container
 -       * @param array $readGrps List of read access routes
 -       * @param array $writeGrps List of write access routes
         * @return Status
         */
        protected function setContainerAccess(
         * This is for Rackspace/Akamai CDNs.
         *
         * @param array $objects List of CF_Object items
 -       * @return void
         */
        public function purgeCDNCache( array $objects ) {
                if ( $this->swiftUseCDN && $this->swiftCDNPurgable ) {
                        }
                        $this->conn = new CF_Connection( $this->auth );
                }
 +
                return $this->conn;
        }
  
        /**
         * Close the connection to the Swift proxy
 -       *
 -       * @return void
         */
        protected function closeConnection() {
                if ( $this->conn ) {
                                );
                        }
                }
 +
                return $this->connContainerCache->get( $container, 'obj' );
        }
  
         * Delete a Swift container
         *
         * @param string $container Container name
 -       * @return void
         * @throws CloudFilesException
         */
        protected function deleteContainer( $container ) {
         * This also sets the Status object to have a fatal error.
         *
         * @param Exception $e
 -       * @param Status $status|null
 +       * @param Status $status null
         * @param string $func
         * @param array $params
 -       * @return void
         */
        protected function handleException( Exception $e, $status, $func, array $params ) {
                if ( $status instanceof Status ) {
  class SwiftFileOpHandle extends FileBackendStoreOpHandle {
        /** @var CF_Async_Op */
        public $cfOp;
 -      /** @var Array */
 +
 +      /** @var array */
        public $affectedObjects = array();
  
        /**
   * @ingroup FileBackend
   */
  abstract class SwiftFileBackendList implements Iterator {
 -      /** @var Array List of path or (path,stat array) entries */
 +      /** @var array List of path or (path,stat array) entries */
        protected $bufferIter = array();
 -      protected $bufferAfter = null; // string; list items *after* this path
 -      protected $pos = 0; // integer
 -      /** @var Array */
 +
 +      /** @var string List items *after* this path */
 +      protected $bufferAfter = null;
 +
 +      /** @var int */
 +      protected $pos = 0;
 +
 +      /** @var array */
        protected $params = array();
  
        /** @var SwiftFileBackend */
        protected $backend;
 -      protected $container; // string; container name
 -      protected $dir; // string; storage directory
 -      protected $suffixStart; // integer
 +
 +      /** @var string Container name */
 +      protected $container;
 +
 +      /** @var string Storage directory */
 +      protected $dir;
 +
 +      /** @var int */
 +      protected $suffixStart;
  
        const PAGE_SIZE = 9000; // file listing buffer size
  
  
        /**
         * @see Iterator::key()
 -       * @return integer
 +       * @return int
         */
        public function key() {
                return $this->pos;
  
        /**
         * @see Iterator::next()
 -       * @return void
         */
        public function next() {
                // Advance to the next file in the page
  
        /**
         * @see Iterator::rewind()
 -       * @return void
         */
        public function rewind() {
                $this->pos = 0;
         *
         * @param string $container Resolved container name
         * @param string $dir Resolved path relative to container
 -       * @param string $after|null
 -       * @param integer $limit
 +       * @param string $after null
 +       * @param int $limit
         * @param array $params
 -       * @return Traversable|Array
 +       * @return Traversable|array
         */
        abstract protected function pageFromList( $container, $dir, &$after, $limit, array $params );
  }
@@@ -1764,12 -1686,7 +1764,12 @@@ class SwiftFileBackendDirList extends S
  
        /**
         * @see SwiftFileBackendList::pageFromList()
 -       * @return Array
 +       * @param string $container
 +       * @param string $dir
 +       * @param string $after
 +       * @param int $limit
 +       * @param array $params
 +       * @return array
         */
        protected function pageFromList( $container, $dir, &$after, $limit, array $params ) {
                return $this->backend->getDirListPageInternal( $container, $dir, $after, $limit, $params );
@@@ -1791,18 -1708,12 +1791,18 @@@ class SwiftFileBackendFileList extends 
                        $storageDir = rtrim( $this->params['dir'], '/' );
                        $this->backend->loadListingStatInternal( "$storageDir/$relPath", $stat );
                }
 +
                return $relPath;
        }
  
        /**
         * @see SwiftFileBackendList::pageFromList()
 -       * @return Array
 +       * @param string $container
 +       * @param string $dir
 +       * @param string $after
 +       * @param int $limit
 +       * @param array $params
 +       * @return array
         */
        protected function pageFromList( $container, $dir, &$after, $limit, array $params ) {
                return $this->backend->getFileListPageInternal( $container, $dir, $after, $limit, $params );